﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Magiq.Objects;

namespace Magiq {
    public static class Magiq {
        private static readonly MagiqToObjects Default = new MagiqToObjects();
        private static readonly IList<IMagiqProvider> Factories = new List<IMagiqProvider>();

        static Magiq() {
            Register(Default);
        }

        public static IMagiqConfigurator NoDefault() {
            return new Configurator().NoDefault();
        }

        public static IMagiqConfigurator Register<T>() where T : IMagiqProvider, new() {
            return new Configurator().Register<T>();
        }

        public static IMagiqConfigurator Register(IMagiqProvider magiqToSomething) {
            return new Configurator().Register(magiqToSomething);
        }

        public static IMagiqProvider For(IEnumerable source) {
            return Factories.FirstOrDefault(x => x.Handles(source));
        }

        public static IMagiqProvider For(IEnumerable source, IEnumerable destination) {
            return Factories.FirstOrDefault(x => x.Handles(source, destination));
        }

        public static IMagiqConfigurator Clear() {
            Factories.Clear();
            return Register(Default);
        }

        #region Nested type: Configurator

        private class Configurator : IMagiqConfigurator {
            #region IMagiqConfigurator Members

            public IMagiqConfigurator Register<T>() where T : IMagiqProvider, new() {
                return Register(new T());
            }

            public IMagiqConfigurator Register(IMagiqProvider magiqToSomething) {
                Factories.Insert(0, magiqToSomething);
                return this;
            }

            public IMagiqConfigurator NoDefault() {
                if (Factories.Contains(Default))
                    Factories.Remove(Default);
                return this;
            }

            #endregion
        }

        #endregion
    }
}